using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using FarseerGames.FarseerPhysics;
using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Dynamics;
using FarseerGames.FarseerPhysics.Dynamics.Joints;
using FarseerGames.FarseerPhysics.Factories;

namespace TileEngine
{
    public class Player
    {
        Level level;

        public Body body;
        public Geom geom;
        public Geom feetGeom;

        public Vector2 position;
        public int Width = 50;
        public int Height = 170;

        private SpriteEffects spriteEffect;
       
        // Jumping states.
        public bool isJumping = false;
        public bool IsOnGround = false;

        public string CurrentAnimation = "rex walking";
        CelAnimationManager cam;

        public bool isMoving = false;

        public Player(Level level)
        {
            this.level = level;
            position = new Vector2(100, 550);//(800 / 2) - (Width / 2), 300);
            cam = (CelAnimationManager)level.Game.Services.GetService(typeof(ICelAnimationManager));    
        }

        public bool OnCollision(Geom geom1, Geom geom2, ContactList contactList)
        {
            body.LinearVelocity.X = 0;
            return true;
        }

        public void Load(ref PhysicsSimulator physicsSimulator)
        {
            body = BodyFactory.Instance.CreateRectangleBody(physicsSimulator, Width, Height, 12.5f);
            body.Position = new Vector2(position.X, position.Y);
            body.MomentOfInertia = float.PositiveInfinity;
            
            geom = GeomFactory.Instance.CreateRectangleGeom(physicsSimulator, body, Width, Height);
            geom.OnCollision += OnCollision;

            // Animations
            cam.AddAnimation("rex walking", "rex walking", new CelCount(4, 1), 6);
            cam.AddAnimation("rex jumping", "rex jumping", new CelCount(1, 1), 0);
        }

        public void Update(GameTime gameTime)
        {
            isJumping = false;
           
            HandleInput();

            Pause(isMoving);
            
            isMoving = false;
            if (body.Position.Y > (level.map.Size.Y * level.map.TileSize.X) + 200)
            {
                body.Position = new Vector2((800 / 2) - (Width / 2), 350);
            }
        }

        public void HandleInput()
        {
            KeyboardState keyboard = Keyboard.GetState();

            CurrentAnimation = "rex walking";

            position = body.Position;

            if (keyboard.IsKeyDown(Keys.Space) || keyboard.IsKeyDown(Keys.Up))
            {
                IsOnGround = false;
                isJumping = true;
                CurrentAnimation = "rex jumping";
                body.ApplyImpulse(new Vector2(0, -450));
            } 

            if (keyboard.IsKeyDown(Keys.Left) || keyboard.IsKeyDown(Keys.A) && !isJumping)
            {   
                body.Position = new Vector2(position.X - 3, position.Y); 
                
                spriteEffect = SpriteEffects.FlipHorizontally;
                isMoving = true;
            }
            if (keyboard.IsKeyDown(Keys.Right) || keyboard.IsKeyDown(Keys.D) && !isJumping)
            {
                body.Position = new Vector2(position.X + 3, position.Y);
                spriteEffect = SpriteEffects.None;
                isMoving = true;
            }
            if (keyboard.IsKeyDown(Keys.Down))
            {
                body.ApplyForce(new Vector2(0, 200));
            }

            // Reset position.
            if (keyboard.IsKeyDown(Keys.R))
            {
                body.Position = new Vector2((800 / 2) - (Width / 2), 300);
            }            
        }

        private void Pause(bool pause)
        {
            cam.ToggleAnimation("rex walking", !pause);
        }

        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            cam.Draw(gameTime, CurrentAnimation, spriteBatch, body.Position, Color.White, spriteEffect, body.Rotation);
        }
    }
}